<?php
require_once 'Sabai/Event.php';

class Sabai_Event_Dispatcher
{
    var $_eventListners = array();

    function addEventListner($eventType, &$listnerHandle, $listnerName = null)
    {
        foreach ((array)$eventType as $event_type) {
            $this->_eventListners[strtolower($event_type)][] = array($listnerName, &$listnerHandle);
        }
    }

    function dispatch($eventType, $eventArgs = array(), $listnerName = null)
    {
        if (isset($listnerName)) {
            $this->dispatchListnerEvent($listnerName, new Sabai_Event($eventType, $eventArgs));
        } else {
            $this->dispatchEvent(new Sabai_Event($eventType, $eventArgs));
        }
    }

    function dispatchEvent(&$event)
    {
        $type = strtolower($event->getType());
        if ($listners = @$this->_eventListners[$type]) {
            $method = 'on' . $type;
            foreach ($listners as $listner) {
                $this->_doDispatchEvent($this->_instantiateListner($listner[1]), $event, $method);
            }
        }
    }

    function dispatchListnerEvent($listnerName, &$event)
    {
        $type = strtolower($event->getType());
        if ($listners = @$this->_eventListners[$type]) {
            $method = 'on' . $type;
            foreach ($listners as $listner) {
                if ($listner[0] == $listnerName) {
                    $this->_doDispatchEvent($this->_instantiateListner($listner[1]), $event, $method);
                    break;
                }
            }
        }
    }

    function &_instantiateListner(&$listner)
    {
        $instance =& $listner->instantiate();
        return $instance;
    }

    function _doDispatchEvent(&$listner, &$event, $method)
    {
        call_user_func_array(array(&$listner, $method), $event->getVars());
    }

    function getEventListners()
    {
        return $this->_eventListners;
    }

    function setEventListners($listners)
    {
        $this->_eventListners = $listners;
    }

    function clearEventListners()
    {
        $this->_eventListners = array();
    }
}